package com.it.flowable.controller;

import com.it.flowable.dto.ActivityHistoryVO;
import com.it.flowable.dto.PageResult;
import com.it.flowable.dto.ProcessInstanceQueryDTO;
import com.it.flowable.dto.ProcessInstanceVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricActivityInstanceQuery;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/process/instance")
@Slf4j
public class ProcessInstanceController {

    @Autowired
    private ProcessInstanceService processInstanceService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private TaskService taskService;

    /**
     * 查询流程实例列表
     */
    @PostMapping("/list")
    public ResponseEntity<PageResult<ProcessInstanceVO>> getProcessInstanceList(
            @RequestBody ProcessInstanceQueryDTO queryDTO) {
        PageResult<ProcessInstanceVO> result = null;
        boolean finished = false;
        // 构建历史流程实例查询
        HistoricProcessInstanceQuery historyQuery = historyService.createHistoricProcessInstanceQuery();

        // 构建条件
        if (StringUtils.isNotBlank(queryDTO.getProcessInstanceId())) {
            historyQuery.processInstanceId(queryDTO.getProcessInstanceId());
        }
        if (StringUtils.isNotBlank(queryDTO.getProcessDefinitionKey())) {
            historyQuery.processDefinitionKey(queryDTO.getProcessDefinitionKey());
        }
        if (StringUtils.isNotBlank(queryDTO.getStartUserId())) {
            historyQuery.startedBy(queryDTO.getStartUserId());
        }

        // 状态过滤
        if ("active".equals(queryDTO.getStatus())) {
            historyQuery.unfinished();
        } else if ("completed".equals(queryDTO.getStatus())) {
            historyQuery.finished();
        } else if ("suspended".equals(queryDTO.getStatus())) {
            // 挂起的流程实例需要从运行时查询
            result = processInstanceService.getSuspendedProcessInstances(queryDTO);
            finished = true;
        }
        if (!finished) {// 计算总数
            long total = historyQuery.count();

            // 分页查询
            List<HistoricProcessInstance> instances = historyQuery
                    .orderByProcessInstanceStartTime().desc()
                    .listPage((queryDTO.getPage() - 1) * queryDTO.getSize(), queryDTO.getSize());

            // 转换为VO
            List<ProcessInstanceVO> vos = instances.stream()
                    .map(processInstanceService::convertToVO)
                    .collect(Collectors.toList());

            result = new PageResult<>(vos, total, queryDTO.getPage(), queryDTO.getSize());
        }

        return ResponseEntity.ok(result);
    }

    /**
     * 获取流程实例的历史活动
     */
    @GetMapping("/{processInstanceId}/activities/history")
    public ResponseEntity<List<ActivityHistoryVO>> getActivityHistory(
            @PathVariable String processInstanceId) {
        HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();

        List<HistoricActivityInstance> activities = historicActivityInstanceQuery
                .processInstanceId(processInstanceId)
                .orderByHistoricActivityInstanceStartTime().asc()
                .list();

        List<ActivityHistoryVO> historyVOs = activities.stream().map(activity -> {
            ActivityHistoryVO vo = new ActivityHistoryVO();
            vo.setActivityId(activity.getActivityId());
            vo.setActivityName(activity.getActivityName());
            vo.setActivityType(activity.getActivityType());
            vo.setStartTime(activity.getStartTime());
            vo.setEndTime(activity.getEndTime());
            vo.setDurationInMillis(activity.getDurationInMillis());
            vo.setAssignee(activity.getAssignee());
            return vo;
        }).collect(Collectors.toList());

        return ResponseEntity.ok(historyVOs);
    }

    /**
     * 获取流程实例详情
     */
    @GetMapping("/{processInstanceId}")
    public ResponseEntity<ProcessInstanceVO> getProcessInstanceDetail(
            @PathVariable String processInstanceId) {
        ProcessInstanceVO detail = processInstanceService.getProcessInstanceDetail(processInstanceId);
        return ResponseEntity.ok(detail);
    }

    /**
     * 挂起流程实例
     */
    @PostMapping("/{processInstanceId}/suspend")
    public ResponseEntity<Void> suspendProcessInstance(@PathVariable String processInstanceId) {
        runtimeService.suspendProcessInstanceById(processInstanceId);
        log.info("挂起流程实例成功: {}", processInstanceId);
        return ResponseEntity.ok().build();
    }

    /**
     * 激活流程实例
     */
    @PostMapping("/{processInstanceId}/activate")
    public ResponseEntity<Void> activateProcessInstance(@PathVariable String processInstanceId) {
        runtimeService.activateProcessInstanceById(processInstanceId);
        log.info("激活流程实例成功: {}", processInstanceId);
        return ResponseEntity.ok().build();
    }

    /**
     * 删除流程实例
     */
    @DeleteMapping("/{processInstanceId}")
    public ResponseEntity<Void> deleteProcessInstance(@PathVariable String processInstanceId) {
        runtimeService.deleteProcessInstance(processInstanceId, "用户手动删除");
        log.info("删除流程实例成功: {}", processInstanceId);
        return ResponseEntity.ok().build();
    }
}